"use strict";
/**
 * @ Author: Yoann Meclot. MSay2
 * @ Created on: 2020-08-28 11:42:33
 * @ Modified on: 2020-09-29 11:12:09
 *
 * @version 1.5
 */
/**
 * Copyright (c) 2020 MSay2, Yoann Meclot - @msay2/tspoet
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
Object.defineProperty(exports, "__esModule", { value: true });
exports.DeclarableType = exports.DeclarableVar = exports.CustomElementBuilder = exports.InterfaceBuilder = exports.EnumBuilder = exports.ClassBuilder = exports.TSType = void 0;
const ArrayList_js_1 = require("../utils/ArrayList.js");
const LinkedMap_js_1 = require("../utils/LinkedMap.js");
const Utils_js_1 = require("../utils/Utils.js");
const CodeWriter_js_1 = require("./CodeWriter.js");
const TSPoet_js_1 = require("./TSPoet.js");
/**
 * @version 1.4
 */
class TSBuilder {
    constructor() {
        this.methods = new ArrayList_js_1.ArrayList();
        this.annotations = new ArrayList_js_1.ArrayList();
        this.importables = new LinkedMap_js_1.LinkedMap();
        this.modifiers = new ArrayList_js_1.ArrayList();
        this.constants = new ArrayList_js_1.ArrayList();
        this.interfaces = new ArrayList_js_1.ArrayList();
        this.variables = new ArrayList_js_1.ArrayList();
        this.docs = new ArrayList_js_1.ArrayList();
        this.interfaceProperties = new ArrayList_js_1.ArrayList();
    }
}
/**
 * @version 1.3
 */
class TSBase {
}
/**
 * Build a new element type.
 *
 * TSType allows to you build a classes, interfaces, custom elements and declarables types and vars.
 *
 * @class TSType
 * @version 1.5
 */
class TSType extends TSBase {
    constructor(builder) {
        super();
        this.owner = Utils_js_1.Utils.checkNotNull(builder, "TSType must have a non-null owner builder.");
        this.name = Utils_js_1.Utils.checkNotNull(builder.name, `TSType for the ${this.owner.constructor.name} builder must have a non-null name (class, enum, interface, declarable).`);
        this.importables = builder.importables;
        this.docs = builder.docs;
        this.superclass = builder.superclass;
        this.annotations = builder.annotations;
        this.transtypeName = builder.transtypeName;
        this.constants = builder.constants;
        this.interfaces = builder.interfaces;
        this.variables = builder.variables;
        this.interfaceProperties = builder.interfaceProperties;
        this.methods = builder.methods;
        this.modifiers = builder.modifiers;
        this.extends = builder.extends;
        this.object = builder.object;
        this.version = builder.version;
        this.type = builder.type;
    }
    /**
     * Init a new builder for create a class.
     *
     * @param name The name of the class.
     * @throws {NullPointerException} Check if the name is null.
     * @type {ClassBuilder}
     * @since 1.0
     */
    static classBuilder(name) {
        return new ClassBuilder(name);
    }
    /**
     * Init a new builder for create a enumeration.
     *
     * @param name The name of the enum.
     * @throws {NullPointerException} Check if the name is null.
     * @type {EnumBuilder}
     * @since 1.0
     */
    static enumBuilder(name) {
        return new EnumBuilder(name);
    }
    /**
     * Init a new builder for create a interface.
     *
     * @param name The name of the interface.
     * @throws {NullPointerException} Check if the name is null.
     * @type {InterfaceBuilder}
     * @since 1.0
     */
    static interfaceBuilder(name) {
        return new InterfaceBuilder(name);
    }
    /**
     * Init a new builder for create a custom element.
     *
     * @param name The name of the custom element tag.
     * @throws {NullPointerException} Check if the name is null.
     * @type {CustomElementBuilder}
     * @since 1.2
     */
    static customElementBuilder(name) {
        return new CustomElementBuilder(name);
    }
    /**
     * Init a new builder for create a declarable type or var.
     *
     * @type {DeclarableBuilder}
     * @since 1.4
     */
    static declarableBuilder() {
        return new DeclarableBuilder();
    }
    emitClass(codeWriter) {
        if (!this.importables.isEmpty()) {
            for (let entry of this.importables.entries()) {
                let path = entry.getKey();
                let nameClasses = entry.getValue();
                codeWriter.emitImports(path, nameClasses);
            }
            codeWriter.emit(CodeWriter_js_1.CodeWriter.NEW_LINE);
        }
        if (!this.docs.isEmpty()) {
            codeWriter.emitDocs(this.docs);
        }
        if (!this.annotations.isEmpty()) {
            for (let entry of this.annotations.entries()) {
                codeWriter.emit(entry.getValue().emit(new CodeWriter_js_1.CodeWriter(codeWriter.indents)).toString());
            }
        }
        if (!this.modifiers.isEmpty()) {
            if (!this.modifiers.contains(TSPoet_js_1.Modifier.PUBLIC) || !this.modifiers.contains(TSPoet_js_1.Modifier.STATIC)) {
                codeWriter.emitModifiers(this.modifiers);
            }
        }
        codeWriter.emitClass(!this.modifiers.isEmpty());
        codeWriter.emit(` ${this.name}`);
        if (this.transtypeName != null) {
            codeWriter.emit(`<${this.transtypeName}>`);
        }
        if (this.superclass != null && this.superclass.getName() != null) {
            codeWriter.emit(` extends ${this.superclass.getName()}`);
        }
        if (!this.interfaces.isEmpty()) {
            codeWriter.emit(" implements ");
            for (let entry of this.interfaces.entries()) {
                codeWriter.emit(entry.getValue().getName()).emit((entry.isLastData() ? "" : ", "));
            }
        }
        codeWriter.emitStartBlock();
        if (!this.variables.isEmpty()) {
            for (let entry of this.variables.entries()) {
                codeWriter.emit(entry.getValue().emit(new CodeWriter_js_1.CodeWriter(codeWriter.indents)).toString());
                if (entry.isLastData()) {
                    codeWriter.emit(CodeWriter_js_1.CodeWriter.NEW_LINE);
                }
            }
        }
        if (!this.methods.isEmpty()) {
            for (let entry of this.methods.entries()) {
                codeWriter.emit(entry.getValue().emit(new CodeWriter_js_1.CodeWriter(codeWriter.indents)).toString());
                if (!entry.isLastData()) {
                    codeWriter.emit(CodeWriter_js_1.CodeWriter.NEW_LINE);
                }
            }
        }
        codeWriter.emitEndBlock();
        return codeWriter;
    }
    emitEnum(codeWriter) {
        if (!this.docs.isEmpty()) {
            codeWriter.emitDocs(this.docs);
        }
        let hasModifiers = this.modifiers.isEmpty();
        if (!hasModifiers) {
            codeWriter.emitModifiers(this.modifiers);
        }
        codeWriter.emitEnum(!hasModifiers);
        codeWriter.emit(` ${this.name}`);
        codeWriter.emitStartBlock();
        if (!this.constants.isEmpty()) {
            codeWriter.emitConstants(this.constants);
        }
        codeWriter.emitEndBlock();
        return codeWriter;
    }
    emitInterface(codeWriter) {
        if (!this.importables.isEmpty()) {
            for (let entry of this.importables.entries()) {
                let path = entry.getKey();
                let nameClasses = entry.getValue();
                codeWriter.emitImports(path, nameClasses);
            }
        }
        if (!this.docs.isEmpty()) {
            codeWriter.emitDocs(this.docs);
        }
        let hasModifiers = this.modifiers.isEmpty();
        if (!hasModifiers) {
            if (this.modifiers.contains(TSPoet_js_1.Modifier.PUBLIC) || this.modifiers.contains(TSPoet_js_1.Modifier.STATIC)) {
                throw "A enumeration don't have the modifiers : PUBLIC or STATIC.";
            }
            else {
                codeWriter.emitModifiers(this.modifiers);
            }
        }
        codeWriter.emitInterface(!hasModifiers);
        codeWriter.emit(` ${this.name}`);
        if (this.transtypeName != null) {
            codeWriter.emit(`<${this.transtypeName}>`);
        }
        if (this.superclass != null && this.superclass.getName() != null) {
            codeWriter.emit(` extends ${this.superclass.getName()}`);
        }
        codeWriter.emitStartBlock();
        if (!this.interfaceProperties.isEmpty()) {
            codeWriter.emitProperties(this.interfaceProperties);
        }
        codeWriter.emitEndBlock();
        return codeWriter;
    }
    emitCustomElement(codeWriter) {
        if (this.extends != undefined && this.extends != null && this.object != undefined && this.object != null && this.name != undefined && this.name != null) {
            codeWriter.emit(`customElements.define("${this.name}", ${this.object.name}, {extends: "${this.extends}"});`).emit(CodeWriter_js_1.CodeWriter.NEW_LINE);
        }
        return codeWriter;
    }
    emitVar(codeWriter) {
        if (!this.importables.isEmpty()) {
            for (let entry of this.importables.entries()) {
                let path = entry.getKey();
                let nameClasses = entry.getValue();
                codeWriter.emitImports(path, nameClasses);
            }
        }
        let hasModifiers = this.modifiers.isEmpty();
        if (!hasModifiers) {
            if (this.modifiers.contains(TSPoet_js_1.Modifier.PUBLIC) || this.modifiers.contains(TSPoet_js_1.Modifier.STATIC)) {
                throw "A enumeration don't have the modifiers : PUBLIC or STATIC.";
            }
            else {
                codeWriter.emitModifiers(this.modifiers);
            }
        }
        codeWriter.emit((!hasModifiers ? " declare " : "declare ")).emit(`${this.version} ${this.name}:`);
        codeWriter.emitStartBlock();
        if (!this.interfaceProperties.isEmpty()) {
            codeWriter.emitProperties(this.interfaceProperties);
        }
        codeWriter.emitEndBlock();
        return codeWriter;
    }
    emitType(codeWriter) {
        if (!this.modifiers.isEmpty()) {
            codeWriter.emitModifiers(this.modifiers);
            codeWriter.emit(" ");
        }
        codeWriter.emit(`declare ${this.version} ${this.name} = ${this.type.getName()};`);
        return codeWriter;
    }
}
exports.TSType = TSType;
/**
 * @version 1.1
 * @since 1.0
 */
class ClassBuilder extends TSBuilder {
    constructor(name) {
        super();
        this.name = name;
    }
    /**
     * Add a importation for the class.
     *
     * @param tsImport The TSImport object for join the values of your importation.
     * @throws {NullPointerException} Check if the import is null.
     * @type {ClassBuilder}
     * @since 1.0
     */
    addImport(path, ...nameClasses) {
        this.importables.add(Utils_js_1.Utils.checkNotNull(path, "TSType for the ClassBuilder object must have a non-null path for importation."), Utils_js_1.Utils.checkNotNull(ArrayList_js_1.Arrays.asList(nameClasses), "TSType for the ClassBuilder object must have a non-null name classes for the importations."));
        return this;
    }
    /**
     * Add a documentation.
     *
     * @param arg Your comment.
     * @type {ClassBuilder}
     * @since 1.1
     */
    addDoc(arg) {
        this.docs.add(Utils_js_1.Utils.checkNotNull(arg, "TSType for the ClassBuilder object must have a non-null doc."));
        return this;
    }
    /**
     * Add modifiers for the class.
     *
     * @param modifiers The modifiers to be added.
     * @throws {NullPointerException} Check if the modifiers is null.
     * @type {ClassBuilder}
     * @since 1.0
     */
    addModifiers(...modifiers) {
        this.modifiers = ArrayList_js_1.Arrays.asList(Utils_js_1.Utils.checkNotNull(modifiers, "TSType for the ClassBuilder object must have a non-null modifiers."));
        return this;
    }
    /**
     * Add a annotation for the class.
     *
     * @param tsAnnotation The annotation to be added.
     * @throws {NullPointerException} Check if the TSAnnotation object is null.
     * @type {ClassBuilder}
     * @since 1.0
     */
    addAnnotation(tsAnnotation) {
        this.annotations.add(Utils_js_1.Utils.checkNotNull(tsAnnotation, "TSType for the ClassBuilder object must have a non-null annotation."));
        return this;
    }
    /**
     * Add a method for the class.
     *
     * @param tsMethod The method to be added.
     * @throws {NullPointerException} Check if the TSMethod object is null.
     * @type {ClassBuilder}
     * @since 1.0
     */
    addMethod(tsMethod) {
        this.methods.add(Utils_js_1.Utils.checkNotNull(tsMethod, "TSType for the ClassBuilder object must have a non-null method."));
        return this;
    }
    /**
     * Add a variable for the class.
     *
     * @param tsVariable The variable to be added.
     * @throws {NullPointerException} Check if the TSVaraible object is null.
     * @type {ClassBuilder}
     * @since 1.0
     */
    addVariable(tsVariable) {
        this.variables.add(Utils_js_1.Utils.checkNotNull(tsVariable, "TSType for the ClassBuilder object must have a non-null variable."));
        return this;
    }
    /**
     * Set a super class for the class.
     *
     * @param typeName The type of the super class.
     * @throws {NullPointerException} Check if the TypeName object is null.
     * @type {ClassBuilder}
     * @since 1.0
     */
    setSuperclass(typeName) {
        this.superclass = Utils_js_1.Utils.checkNotNull(typeName, "TSType for the ClassBuilder object must have a non-null super class.");
        return this;
    }
    /**
     * Add a interface to implement for the class.
     *
     * @param typeName The return type.
     * @throws {NullPointerException} Check if the TypeName object is null.
     * @type {ClassBuilder}
     * @since 1.0
     */
    addInterface(typeName) {
        this.interfaces.add(Utils_js_1.Utils.checkNotNull(typeName, "TSType for the ClassBuilder object must have a non-null interface."));
        return this;
    }
    /**
     * Transtype your class.
     *
     * @param objectName The name of your object to transtype.
     * @throws {NullPointerException} Check if the object name is null.
     * @type {ClassBuilder}
     * @since 1.0
     */
    transtypeTo(objectName) {
        this.transtypeName = Utils_js_1.Utils.checkNotNull(objectName, "TSType for the ClassBuilder object must have a non-null object name to transtypation.");
        return this;
    }
    /**
     * Build the class.
     *
     * @throws {NullPointerException} Check if the name is null.
     * @throws {NullPointerException} Check if the imports is null.
     * @throws {NullPointerException} Check if the modifiers is null.
     * @throws {NullPointerException} Check if the annotations is null.
     * @throws {NullPointerException} Check if the methods is null.
     * @throws {NullPointerException} Check if the variable is null.
     * @throws {NullPointerException} Check if the super class is null.
     * @throws {NullPointerException} Check if the interface is null.
     * @type {TSType}
     * @since 1.0
     */
    build() {
        return new TSType(this);
    }
}
exports.ClassBuilder = ClassBuilder;
/**
 * @version 1.1
 * @since 1.0
 */
class EnumBuilder extends TSBuilder {
    constructor(name) {
        super();
        this.name = name;
    }
    /**
     * Add modifiers for the enumeration.
     *
     * @param modifiers The modifiers to be added.
     * @throws {NullPointerException} Check if the modifiers is null.
     * @type {EnumBuilder}
     * @since 1.0
     */
    addModifiers(...modifiers) {
        this.modifiers = ArrayList_js_1.Arrays.asList(Utils_js_1.Utils.checkNotNull(modifiers, "TSType for the EnumBuilder object must have a non-null modifiers."));
        return this;
    }
    /**
     * Add a documentation.
     *
     * @param arg Your comment.
     * @type {EnumBuilder}
     * @since 1.1
     */
    addDoc(arg) {
        this.docs.add(Utils_js_1.Utils.checkNotNull(arg, "TSType for the EnumBuilder object must have a non-null doc."));
        return this;
    }
    /**
     * Add a constant for the enumearation.
     *
     * @param tsConstant The constant to be added.
     * @throws {NullPointerException} Check if the TSConstant object is null.
     * @type {EnumBuilder}
     * @since 1.0
     */
    addConstant(tsConstant) {
        this.constants.add(Utils_js_1.Utils.checkNotNull(tsConstant, "TStype for the EnumBuilder object must have a non-null constant."));
        return this;
    }
    /**
     * Build the enumeration.
     *
     * @throws {NullPointerException} Check if the name is null.
     * @throws {NullPointerException} Check if the modifiers is null.
     * @throws {NullPointerException} Check if the constant is null.
     * @type {TSType}
     * @since 1.0
     */
    build() {
        return new TSType(this);
    }
}
exports.EnumBuilder = EnumBuilder;
/**
 * @version 1.1
 * @since 1.0
 */
class InterfaceBuilder extends TSBuilder {
    constructor(name) {
        super();
        this.name = name;
    }
    /**
     * Add a importation for the interface.
     *
     * @param tsImport The import to be added.
     * @throws {NullPointerException} Check if the TSImport object is null.
     * @type {InterfaceBuilder}
     * @since 1.0
     */
    addImport(path, ...nameClasses) {
        this.importables.add(Utils_js_1.Utils.checkNotNull(path, "TSType for the InterfaceBuilder object must have a non-null path for importation."), Utils_js_1.Utils.checkNotNull(ArrayList_js_1.Arrays.asList(nameClasses), "TSType for the InterfaceBuilder object must have a non-null name classes for the importations."));
        return this;
    }
    /**
     * Add a documentation.
     *
     * @param arg Your comment.
     * @type {InterfaceBuilder}
     * @since 1.1
     */
    addDoc(arg) {
        this.docs.add(Utils_js_1.Utils.checkNotNull(arg, "TSType for the InterfaceBuilder object must have a non-null doc."));
        return this;
    }
    /**
     * Set a super class for th interface.
     *
     * @param typeName The type of the super class.
     * @throws {NullPointerException} Check if the TypeName object is null.
     * @type {InterfaceBuilder}
     * @since 1.0
     */
    setSuperclass(typeName) {
        this.superclass = Utils_js_1.Utils.checkNotNull(typeName, "TSType for the InterfaceBuilder object must have a non-null super class.");
        return this;
    }
    /**
     * Add modifiers for the interface.
     *
     * @param modifiers The modifiers to be added.
     * @throws {NullPointerException} Check if the modifiers is null.
     * @type {InterfaceBuilder}
     * @since 1.0
     */
    addModifiers(...modifiers) {
        this.modifiers = ArrayList_js_1.Arrays.asList(Utils_js_1.Utils.checkNotNull(modifiers, "TSType for the InterfaceBuilder object must have a non-null modifiers."));
        return this;
    }
    /**
     * Add a property or methods for the interface.
     *
     * @param tsProerty The interface property.
     * @throws {NullPointerException} Check if the TSProperty object is null.
     * @type {InterfaceBuilder}
     * @since 1.0
     */
    addProperty(tsProerty) {
        this.interfaceProperties.add(Utils_js_1.Utils.checkNotNull(tsProerty, "TSType for InterfaceBuilder object must have a non-null property."));
        return this;
    }
    /**
     * Transtype the Interface.
     *
     * @param objectName The name of your object to transtype.
     * @throws {NullPointerException} Check if the object name is null.
     * @type {InterfaceBuilder}
     * @since 1.0
     */
    transtypeTo(objectName) {
        this.transtypeName = Utils_js_1.Utils.checkNotNull(objectName, "TSType for the InterfaceBuilder object must have a non-null object name for the transtypation.");
        return this;
    }
    /**
     * Build the interface.
     *
     * @throws {NullPointerException} Check if the name is null.
     * @throws {NullPointerException} Check if the import is null.
     * @throws {NullPointerException} Check if the super class is null.
     * @throws {NullPointerException} Check if the modifiers is null.
     * @throws {NullPointerException} Check if the method is null.
     * @throws {NullPointerException} Check if the property is null.
     * @type {TSType}
     * @since 1.0
     */
    build() {
        return new TSType(this);
    }
}
exports.InterfaceBuilder = InterfaceBuilder;
/**
 * @version 1.0
 * @since 1.2
 */
class CustomElementBuilder extends TSBuilder {
    constructor(name) {
        super();
        this.name = Utils_js_1.Utils.checkNotNull(name, "TSType must have a non-null name of your custom element.");
    }
    /**
     * Set the reference object.
     *
     * @param tsObject The reference of the object.
     * @throws {NullPointerException} Check if the TSObject object is null.
     * @type {CustomElementBuilder}
     * @since 1.0
     */
    setObject(tsObject) {
        this.object = Utils_js_1.Utils.checkNotNull(tsObject, "TSType for the CustomElementBuilder object must have a non-null object for your custom element.");
        return this;
    }
    /**
     * Set a super class for the custom element.
     *
     * @param superclass The super class name (div, button ...etc).
     * @throws {NullPointerException} Check if the super class name is null.
     * @type {CustomElementBuilder}
     * @since 1.0
     */
    setSuperclass(superclass) {
        this.extends = Utils_js_1.Utils.checkNotNull(superclass, "TStype for the CustomElementBuilder object must have a non-null super class name.");
        return this;
    }
    /**
     * Build a custom element.
     *
     * @throws {NullPointerException} Check if the name is null.
     * @type {TSType}
     * @since 1.0
     */
    build() {
        return new TSType(this);
    }
}
exports.CustomElementBuilder = CustomElementBuilder;
/**
 * @version 1.0
 * @since 1.4
 */
class DeclarableBuilder {
    constructor() { }
    /**
     * Init a new declarable var.
     *
     * @type {DeclarableVar}
     * @since 1.0
     */
    forVar() {
        return new DeclarableVar();
    }
    /**
     * Init a new declarable type.
     *
     * @param name The name of type.
     * @type {DeclarableType}
     * @since 1.0
     */
    forType(name) {
        return new DeclarableType(name);
    }
}
DeclarableBuilder.VAR = "var";
DeclarableBuilder.TYPE = "type";
/**
 * @version 1.0
 * @since 1.4
 */
class DeclarableVar extends TSBuilder {
    constructor() {
        super();
        this.version = DeclarableBuilder.VAR;
    }
    /**
     * Join your interface builder for create a var declarable.
     *
     * This method ignore the super class.
     *
     * @param interfaceBuilder The interface builder.
     * @throws {NullPointerException} Check if the InterfaceBuilder object is null.
     * @type {DeclarableVar}
     * @since 1.0
     */
    add(interfaceBuilder) {
        this.interface = Utils_js_1.Utils.checkNotNull(interfaceBuilder, "TSType for DeclarableVar must have a non-null interface builder.");
        this.name = this.interface.name;
        this.importables = this.interface.importables;
        this.modifiers = this.interface.modifiers;
        this.interfaceProperties = this.interface.interfaceProperties;
        this.transtypeName = this.interface.transtypeName;
        return this;
    }
    /**
     * Build declarable var.
     *
     * @throws {NullPointerException} Check if the name is null.
     * @throws {NullPointerException} Check if the import is null.
     * @throws {NullPointerException} Check if the modifiers is null.
     * @throws {NullPointerException} Check if the method is null.
     * @throws {NullPointerException} Check if the property is null.
     * @type {TSType}
     * @since 1.0
     */
    build() {
        return new TSType(this);
    }
}
exports.DeclarableVar = DeclarableVar;
/**
 * @version 1.0
 * @since 1.4
 */
class DeclarableType extends TSBuilder {
    constructor(name) {
        super();
        this.name = name;
        this.version = DeclarableBuilder.TYPE;
    }
    /**
     * Add new modifiers.
     *
     * @param modifiers The modifiers to be added.
     * @throws {NullPointerException} Checkif the modifiers is null.
     * @type {DeclarableType}
     * @since 1.0
     */
    addModifiers(...modifiers) {
        this.modifiers = ArrayList_js_1.Arrays.asList(Utils_js_1.Utils.checkNotNull(modifiers, "TSType for DeclarableType must have a non-null modifiers."));
        return this;
    }
    /**
     * Set a return type for declarable type.
     *
     * @param typeName The return type.
     * @throws {NullPointerException} Check if the TypeName object is null.
     * @type {DeclarableType}
     * @since 1.0
     */
    return(typeName) {
        this.type = Utils_js_1.Utils.checkNotNull(typeName, "TSType for DeclarableType must have a non-null type name.");
        return this;
    }
    /**
     * Build a declarable type.
     *
     * @throws {NullPointerException} Check if the name is null.
     * @throws {NullPointerException} Check if the modifiers is null.
     * @type {TSType}
     * @since 1.0
     */
    build() {
        return new TSType(this);
    }
}
exports.DeclarableType = DeclarableType;
//# sourceMappingURL=TSType.js.map